package cn.edu.ncut.cs.springboot.petmanagementsystem.Config;

import cn.edu.ncut.cs.springboot.petmanagementsystem.Util.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain)
            throws ServletException, IOException {

        // 获取请求路径
        String requestPath = request.getRequestURI();
        String servletPath = request.getServletPath(); // servlet path
        String contextPath = request.getContextPath(); // context-path
        
        // 日志记录请求信息（用于调试）
        log.info("JWT Filter - Request URI: {}, Servlet Path: {}, Context Path: {}, Method: {}", 
            requestPath, servletPath, contextPath, request.getMethod());
        
        // 如果是登录、注册等公开接口，直接放行（避免JWT过滤器干扰）
        // 从日志看，servletPath是 /api/auth/login，所以需要检查包含/api的路径
        boolean isPublicPath = false;
        
        // 检查servletPath和requestPath（可能包含/api前缀）
        if (servletPath != null) {
            isPublicPath = servletPath.contains("/api/auth/login") ||
                          servletPath.contains("/api/auth/register") ||
                          servletPath.contains("/api/user/register") ||
                          servletPath.contains("/api/sale-pet/list") ||
                          servletPath.contains("/api/pet/list") ||
                          servletPath.contains("/api/product/list") ||
                          servletPath.contains("/api/swagger-ui") ||
                          servletPath.contains("/api/v3/api-docs") ||
                          servletPath.contains("/api/ws/") ||
                          servletPath.contains("/ws/") ||
                          servletPath.startsWith("/api/auth/") ||
                          servletPath.startsWith("/auth/") ||
                          servletPath.equals("/error") ||
                          servletPath.equals("/favicon.ico") ||
                          servletPath.startsWith("/sale-pet/list") ||
                          servletPath.startsWith("/pet/list") ||
                          servletPath.startsWith("/product/list");
        }
        
        // 如果servletPath检查没通过，再检查完整requestPath
        if (!isPublicPath && requestPath != null) {
            isPublicPath = requestPath.contains("/api/auth/login") ||
                          requestPath.contains("/api/auth/register") ||
                          requestPath.contains("/api/user/register") ||
                          requestPath.contains("/api/sale-pet/list") ||
                          requestPath.contains("/api/pet/list") ||
                          requestPath.contains("/api/product/list") ||
                          requestPath.contains("/api/swagger-ui") ||
                          requestPath.contains("/api/v3/api-docs") ||
                          requestPath.contains("/api/ws/") ||
                          requestPath.contains("/ws/") ||
                          requestPath.startsWith("/api/auth/") ||
                          requestPath.startsWith("/auth/") ||
                          requestPath.endsWith("/error") ||
                          requestPath.endsWith("/favicon.ico") ||
                          requestPath.contains("/sale-pet/list") ||
                          requestPath.contains("/pet/list") ||
                          requestPath.contains("/product/list");
        }
        
        if (isPublicPath) {
            log.debug("JWT Filter - 公开接口，直接放行: {} (servletPath: {})", requestPath, servletPath);
            filterChain.doFilter(request, response);
            return;
        }

        String header = request.getHeader("Authorization");

        // 1️⃣ 无 Token 或非 Bearer 开头则放行
        if (header == null || !header.startsWith("Bearer ")) {
            filterChain.doFilter(request, response);
            return;
        }

        String token = header.substring(7);
        try {
            // 2️⃣ 解析 JWT
            Jws<Claims> claimsJws = JwtUtil.parseToken(token);
            Claims claims = claimsJws.getBody();

            String username = claims.getSubject();
            Object roleObj = claims.get("role");

            // 3️⃣ 已经认证的不重复处理
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                List<SimpleGrantedAuthority> authorities;

                if (roleObj instanceof String) {
                    authorities = List.of(new SimpleGrantedAuthority((String) roleObj));
                } else if (roleObj instanceof List) {
                    authorities = ((List<?>) roleObj)
                            .stream()
                            .map(Object::toString)
                            .map(SimpleGrantedAuthority::new)
                            .collect(Collectors.toList());
                } else {
                    authorities = List.of();
                }

                // 4️⃣ 构造认证对象
                UsernamePasswordAuthenticationToken authentication =
                        new UsernamePasswordAuthenticationToken(username, null, authorities);

                SecurityContextHolder.getContext().setAuthentication(authentication);
            }

        } catch (Exception e) {
            // 5️⃣ 解析异常，记录日志但不阻止请求（让Security继续处理）
            log.debug("JWT解析失败: {}", e.getMessage());
            // 不清除SecurityContext，让后续的Security过滤器处理
            filterChain.doFilter(request, response);
            return;
        }

        // 6️⃣ 继续过滤器链
        filterChain.doFilter(request, response);
    }
}
